4
4
.
.
2
2
.
.
3
3
N
N
a
a
v
v
i
i
g
g
a
a
t
t
i
i
o
o
n
n
V
V
i
i
e
e
w
w
I
I
n
n
f
f
o
o
[
[
R
R
]
]
NavigationView is Container View that allows you to switch Screens by using NavigatinLinks and Back Button.
First you need to enclose one Initial View inside NavigationView.
Then as you go to other Views, using NavigatinLinks, you get a Back Button to go back to previous Views.
Error: NavigationLink Works Only Once
Different ways of defining navigation link
NavigationLink("Go To Second Screen", destination: SecondScreen(name: "John")) //Simple text Link
NavigationLink(destination: SecondScreen(name: "John")) { Text("Go To Second Screen") } //Complex Link
Content
Basic Example
With Bar Title
With Custom View
Programmatically activate Link - Using isActive
Programmatically activate Link - Using selection
Add Custom Bar Buttons
Hide Navigation & Status Bar
Pass data using Environment
B
B
a
a
s
s
i
i
c
c
E
E
x
x
a
a
m
m
p
p
l
l
e
e
In this example each Screen shows a simple Text View.
We are using simple text as a link.
ContentView.swift
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: Text("John Details"))
NavigationLink("Link to Bill", destination: Text("Bill Details"))
}
}
}
}
Initial Screen John Screen
W
W
i
i
t
t
h
h
B
B
a
a
r
r
T
T
i
i
t
t
l
l
e
e
In this example for each Screen we also specify Title that should be shown on top of the Screen.
ContentView.swift
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: Text("John Details").navigationBarTitle("John Title"))
NavigationLink("Link to Bill", destination: Text("Bill Details").navigationBarTitle("Bill Title"))
}.navigationBarTitle("Content View")
}
}
}
Initial Screen John Screen
W
W
i
i
t
t
h
h
C
C
u
u
s
s
t
t
o
o
m
m
V
V
i
i
e
e
w
w
[
[
R
R
]
]
Yellow line shows how to use NavigatinLink to go to next screen.
Green lines highlighted show how to add title to for each screen (title is displayed in the navigation bar).
Red lines show how to pass a parameter to the SecondScreen and how to read it.
ContentView.swift
//==========================================================================
// ContentView
//==========================================================================
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Content View")
NavigationLink(destination: SecondScreen(name: "John")) { Text("Go To Second Screen") }
}.navigationBarTitle("Content View")
}.navigationViewStyle(StackNavigationViewStyle())
}
}
//==========================================================================
// SecondScreen
//==========================================================================
struct SecondScreen: View {
var name: String
var body: some View {
Text("Hello \(name)").navigationBarTitle("Second Screen")
}
}
Initial Screen Second Screen
P
P
r
r
o
o
g
g
r
r
a
a
m
m
m
m
a
a
t
t
i
i
c
c
a
a
l
l
l
l
y
y
a
a
c
c
t
t
i
i
v
v
a
a
t
t
e
e
L
L
i
i
n
n
k
k
-
-
U
U
s
s
i
i
n
n
g
g
i
i
s
s
A
A
c
c
t
t
i
i
v
v
e
e
This example show how to programmatically activate a link (how to show View by pressing a button instead of a link).
To back to initial View simple deactivate all links.
ContentView.swift
struct ContentView: View {
@State var johnActive : Bool = false
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: Text("John Details"), isActive: $johnActive)
NavigationLink("Link to Bill", destination: Text("Bill Details"))
Button("Show John") { self.johnActive = true }
}
}
}
}
Initial Screen John Screen
P
P
r
r
o
o
g
g
r
r
a
a
m
m
m
m
a
a
t
t
i
i
c
c
a
a
l
l
l
l
y
y
a
a
c
c
t
t
i
i
v
v
a
a
t
t
e
e
L
L
i
i
n
n
k
k
-
-
U
U
s
s
i
i
n
n
g
g
s
s
e
e
l
l
e
e
c
c
t
t
i
i
o
o
n
n
This example show how to programmatically activate a link (go to screen by pressing a button instead of a link).
To go back to initial View set selection = nil.
ContentView.swift
struct ContentView: View {
@State var selection: String? = nil
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: Text("John Details"), tag: "John", selection: $selection)
NavigationLink("Link to Bill", destination: Text("Bill Details"), tag: "Bill", selection: $selection)
Button("Show John") { self.selection = "John" }
}
}
}
}
Initial Screen John Screen
A
A
d
d
d
d
C
C
u
u
s
s
t
t
o
o
m
m
B
B
a
a
r
r
B
B
u
u
t
t
t
t
o
o
n
n
s
s
In this example we add leading and trailing Buttons to the top Bar.
To add multiple buttons on the same side place them inside a HStack.
You can also hide default Back button by using .navigationBarBackButtonHidden(true).
ContentView.swift
//==========================================================================
// ContentView
//==========================================================================
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: SecondScreen(detials: "John Details"))
NavigationLink("Link to Bill", destination: SecondScreen(detials: "Bill Details"))
}
}
}
}
//==========================================================================
// SecondScreen
//==========================================================================
struct SecondScreen: View {
var detials : String
var body: some View {
Text(detials)
.navigationBarTitle("Second Screen")
.navigationBarItems(
leading: Button("Button1") { print("Button1") },
trailing: NavigationLink("Link to Bill", destination: SecondScreen(detials: "Bill Details"))
)
}
}
Initial Screen John Screen
In this version we replace default Back Button and add Forward Button to navigate between Views.
We are using selection property to specify which View should be presented.
Unfortunately there are some problems during navigation where Forward Button is used.
ContentView.swift
//==========================================================================
// ContentView
//==========================================================================
struct ContentView: View {
@State var selection : String? = nil
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John",
destination: SecondScreen(detials: "John Details", selection: $selection),
tag: "John",
selection: $selection
)
NavigationLink("Link to Bill",
destination: SecondScreen(detials: "Bill Details", selection: $selection),
tag: "Bill",
selection: $selection
)
}
}
}
}
//==========================================================================
// SecondScreen
//==========================================================================
struct SecondScreen: View {
var detials : String
@Binding var selection : String? //@Binding allows us to control selection from this View
var body: some View {
Text(detials)
.navigationBarTitle("Second Screen")
.navigationBarBackButtonHidden(true)
.navigationBarItems(
leading: Button("MyBack") { self.selection = nil },
trailing: Button("MyForward") { self.selection = "Bill" }
)
}
}
Initial Screen John Screen
H
H
i
i
d
d
e
e
N
N
a
a
v
v
i
i
g
g
a
a
t
t
i
i
o
o
n
n
&
&
S
S
t
t
a
a
t
t
u
u
s
s
B
B
a
a
r
r
This example show how to hide Navigation & Status Bar.
Navigation Bar doesn't get hidden on initial View.
ContentView.swift
//==========================================================================
// ContentView
//==========================================================================
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink("Link to John", destination: SecondScreen(detials: "John Details"))
NavigationLink("Link to Bill", destination: SecondScreen(detials: "Bill Details"))
}.navigationBarHidden(true)
}.statusBar(hidden: true)
}
}
//==========================================================================
// SecondScreen
//==========================================================================
struct SecondScreen: View {
var detials : String
var body: some View {
Text(detials)
.navigationBarTitle("Second Screen")
.navigationBarHidden(true)
}
}
Initial Screen John Screen
P
P
a
a
s
s
s
s
d
d
a
a
t
t
a
a
u
u
s
s
i
i
n
n
g
g
E
E
n
n
v
v
i
i
r
r
o
o
n
n
m
m
e
e
n
n
t
t
NavigationView automatically shares its environment with any child view that it presents.
Use environmentObject() modifier attached to the navigation view itself.
Then you can create NavigationLink without Parameters since data will be taken from Environment.
ContentView.swift
import SwiftUI
//==========================================================================
// Person
//==========================================================================
class Person : ObservableObject { //Must conform to ObservableObject Protocol
var name = "John" //Otherwise you can't use @EnvironmentObject
}
//==========================================================================
// ContentView
//==========================================================================
struct ContentView: View {
var person = Person()
var body: some View {
NavigationView {
NavigationLink("Link to John", destination: SecondScreen()) //Call link with no arguments
}.envi ronmentObject(person)
}
}
//==========================================================================
// SecondScreen
//==========================================================================
struct SecondScreen: View {
@EnvironmentObject var person : Person //We will take details from Environment
var body: some View {
Text(person.name)
}
}